package com.example.service.authcenter;

import com.example.entity.authcenter.SystemApplication;
import com.example.entity.authcenter.SystemFunction;
import com.example.entity.authcenter.SystemMenu;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import com.example.dao.authcenter.qa.*;
import com.example.dao.authcenter.prd.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * XXX
 *
 * @author : jamesfu
 * @date : 24/6/2019
 * @time : 2:45 PM
 */
@Service
public class SystemMenuSyncService {
    @Autowired
    private SourceSystemApplicationDao sourceSystemApplicationDao;
    @Autowired
    private SourceSystemMenuDao sourceSystemMenuDao;
    @Autowired
    private SourceSystemFunctionDao sourceSystemFunctionDao;

    @Autowired
    private TargetSystemApplicationDao targetSystemApplicationDao;
    @Autowired
    private TargetSystemMenuDao targetSystemMenuDao;
    @Autowired
    private TargetSystemFunctionDao targetSystemFunctionDao;

    public void syncMenu(String sourceAppKey, String targetAppKey) {
        SystemApplication sourceApp = sourceSystemApplicationDao.findAll().stream().filter(item -> item.getApplicationKey().equals(sourceAppKey)).findFirst().get();
        SystemApplication targetApp = targetSystemApplicationDao.findAll().stream().filter(item -> item.getApplicationKey().equals(targetAppKey)).findFirst().get();

        List<SystemMenu> sourceMenuList = sourceSystemMenuDao.findAll().stream().filter(item -> item.getApplicationSysNo().equals(sourceApp.getSysNo())).collect(Collectors.toList());

        List<SystemMenu> sourceRootMenuList = sourceMenuList.stream().filter(item -> item.getParentSysNo() == null || item.getParentSysNo().equals(0)).collect(Collectors.toList());
        for (SystemMenu currentMenuNode : sourceRootMenuList) {
            if ("organization".equals(currentMenuNode.getMenuDomain())) {
                continue;
            }
            processMenu(0, currentMenuNode, sourceMenuList, targetApp);
        }
    }

    public void deleteMenuNode(String targetAppKey, Integer nodeId) {
        SystemApplication targetApp = targetSystemApplicationDao.findAll().stream().filter(item -> item.getApplicationKey().equals(targetAppKey)).findFirst().get();

        List<SystemMenu> targetMenuList = sourceSystemMenuDao.findAll().stream().filter(item -> item.getApplicationSysNo().equals(targetApp.getSysNo())
                && item.getCommonStatus().equals(1)).collect(Collectors.toList());

        SystemMenu targetNode = targetMenuList.stream().filter(item -> item.getSysNo().equals(nodeId)).findFirst().get();
        deleteNode(targetNode, targetMenuList);
    }

    private void deleteNode(SystemMenu targetNode, List<SystemMenu> targetMenuList) {
        targetNode.setCommonStatus(0);
        targetSystemMenuDao.save(targetNode);

        List<SystemMenu> childList = targetMenuList.stream().filter(item -> item.getParentSysNo().equals(targetNode.getSysNo())).collect(Collectors.toList());
        for (SystemMenu child : childList) {
            deleteNode(child, targetMenuList);
        }

    }

    private void processMenu(Integer parentSysNo, SystemMenu currentNode, List<SystemMenu> sourceMenuList, SystemApplication targetApp) {
        SystemMenu newMenuNode = new SystemMenu();
        BeanUtils.copyProperties(currentNode, newMenuNode);
        newMenuNode.setSysNo(null);
        newMenuNode.setParentSysNo(parentSysNo);
        newMenuNode.setApplicationSysNo(targetApp.getSysNo());

        targetSystemMenuDao.save(newMenuNode);

        // 处理菜单下的权限点
        processFunction(currentNode, newMenuNode);

        // 处理子节点
        List<SystemMenu> childList = sourceMenuList.stream().filter(item -> item.getParentSysNo().equals(currentNode.getSysNo())).collect(Collectors.toList());
        for (SystemMenu child : childList) {
            processMenu(newMenuNode.getSysNo(), child, sourceMenuList, targetApp);
        }
    }

    private void processFunction(SystemMenu currentNode, SystemMenu newMenuNode) {
        SystemFunction systemFunction = new SystemFunction();
        systemFunction.setMenuSysNo(currentNode.getSysNo());
        Example<SystemFunction> example = Example.of(systemFunction);
        List<SystemFunction> functionList = sourceSystemFunctionDao.findAll(example);
        if (functionList.size() == 0) {
            return;
        }
        for (SystemFunction functionNode : functionList) {
            SystemFunction newFunctionNode = new SystemFunction();
            BeanUtils.copyProperties(functionNode, newFunctionNode);
            newFunctionNode.setSysNo(null);
            newFunctionNode.setMenuSysNo(newMenuNode.getSysNo());

            targetSystemFunctionDao.save(newFunctionNode);
        }
    }
}
